'use strict'

let models = require('../models');
let menus = require('../../config/menus');

let attendanceService = require('../services/attendance');

let SchoolDao = models.SchoolDao;
let GradeDao = models.GradeDao;
let NatureClassDao = models.NatureClassDao;
let AttendanceCachePersonTimeInfo = models.AttendanceCachePersonTimeInfo;
let AttendanceReportCacheDao = models.AttendanceReportCacheDao;

function calcSchoolStatistics(school, days) {
    school.peopleCount = 0;
    school.grades.forEach(function(grade){
        calcGradeStatistics(grade, days);
        school.peopleCount += grade.peopleCount;
    });
    school.statisticsList = combineStatisticsList(days, school.grades);
}

function calcGradeStatistics(grade, days) {
    grade.natureClasses.forEach(natureClass => {
        calcNatureClassStatistics(natureClass, days);
    });
    grade.statisticsList = combineStatisticsList(days, grade.natureClasses);

    grade.peopleCount = grade.natureClasses.reduce((sum, natureClass) => {
        return sum + natureClass.students.length
    }, 0);
}

function calcNatureClassStatistics(natureClass, days) {
    natureClass.statisticsList = days.map(day => {
        let statistics = {
            day: day,
            statistics: 
                attendanceService.getStatisticsOfNatureClass(
                    natureClass, day.startTime, day.endTime)[0]
        };

        return statistics;
    });
    natureClass.peopleCount = natureClass.students.length;
}

// container必须要有一个属性为statisticsList
function combineStatisticsList(days, containers) {
    let combinedStatisticsList = days.map(day => {
        return {
            day: day,
            statistics: attendanceService.emptyStatistics()
        }
    });

    containers.forEach(container => {
        container.statisticsList.forEach((statistics, index) => {
            attendanceService.combineStatistics(
                combinedStatisticsList[index].statistics,
                statistics.statistics);
        });
    });

    return combinedStatisticsList;
}

function generateDaysInTerm(term) {
    let days = [];
    let now = new Date();

    let startTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, -1, 0);
    let endTime = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 0, -1, 0);

    while ( endTime > term.startTime ) {
        days.push({
            startTime: new Date(startTime.getTime()),
            endTime: new Date(endTime.getTime())
        });

        startTime.setDate(startTime.getDate() - 1);
        endTime.setDate(endTime.getDate() - 1);
    }

    return days;
}

function generateWeeksInTerm(term) {
    let weeks = [];
    let now = new Date();
    // 调整到周日
    now.setDate(now.getDate() - now.getDay());

    let startTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, -1, 0);
    let endTime = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 7, 0, -1, 0);

    while ( endTime > term.startTime ) {
        weeks.push({
            startTime: new Date(startTime.getTime()),
            endTime: new Date(endTime.getTime())
        });

        startTime.setDate(startTime.getDate() - 7);
        endTime.setDate(endTime.getDate() - 7);
    }

    return weeks;
}

function generateMonthsInTerm(term) {
    let months = [];
    let now = new Date();

    now.setDate(1);

    let startTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, -1, 0);
    let endTime = new Date(now.getFullYear(), now.getMonth() + 1, 1, 0, -1, 0);

    while ( endTime > term.startTime ) {
        months.push({
            startTime: new Date(startTime.getTime()),
            endTime: new Date(endTime.getTime())
        });

        startTime = new Date(startTime.getFullYear(), startTime.getMonth(), 1, 0, -1, 0);
        endTime = new Date(startTime.getFullYear(), startTime.getMonth() + 2, 1, 0, -1, 0);
    }

    return months;
}

function countPeriodReport(startDate,endDate,attendanceScope,object) {
    startDate.setHours(0, 0, 0, 0);
    endDate.setHours(0, 0, 0, 0);
    var oneday = 1000 * 60 * 60 * 24;

    let periodCacheInfo = new AttendanceCachePersonTimeInfo();
    periodCacheInfo = initializeInfo(periodCacheInfo);

    console.log(object);
    let school = null, grade = null, natureClass = null;
    switch (attendanceScope) {
        case 0:
            school = SchoolDao.findOne({
                id:object
            });
            break;
        case 1:
            grade = GradeDao.findOne({
                id:object
            });
            break;
        case 2:
            natureClass = NatureClassDao.findOne({
                id:object
            });
            break;
    }

    let dayCaches = {};
    switch (attendanceScope) {
        case 0:
            dayCaches = AttendanceReportCacheDao.find({
                date: {
                    $gte:startDate,
                    $lte:endDate
                },
                school: school.id,
                grade: undefined
            });
            console.log(dayCaches);
            break;
        case 1:
            dayCaches = AttendanceReportCacheDao.find({
                date: {
                    $gte:startDate,
                    $lte:endDate
                },
                grade: grade.id,
                natureClass: undefined
            });
            break;
        case 2:
            dayCaches = AttendanceReportCacheDao.find({
                date: {
                    $gte:startDate,
                    $lte:endDate
                },
                natureClass: natureClass.id
            });
            break;
    }

    dayCaches.forEach(dayCache=>{
        periodCacheInfo = countPersonTimeInfo(periodCacheInfo, dayCache.personTimeInfo);
    });

    return periodCacheInfo;
}

function countPersonTimeInfo(personTimeInfo1,personTimeInfo2){
    personTimeInfo1.absenceCount += personTimeInfo2.absenceCount;
    personTimeInfo1.earlyCount += personTimeInfo2.earlyCount;
    personTimeInfo1.attendCount += personTimeInfo2.attendCount;
    personTimeInfo1.lateCount += personTimeInfo2.lateCount;
    personTimeInfo1.leaveCount += personTimeInfo2.leaveCount;
    return personTimeInfo1;
}

function initializeInfo(info){
    info.absenceCount = 0;
    info.earlyCount = 0;
    info.attendCount = 0;
    info.lateCount = 0;
    info.leaveCount = 0;
    return info;
}


module.exports = {
    calcSchoolStatistics,
    calcGradeStatistics,
    calcNatureClassStatistics,
    generateDaysInTerm,
    generateWeeksInTerm,
    generateMonthsInTerm,
    countPeriodReport
}
